#include "bsp_can.h"
#include "configurations.h"
#include "common_inc.h"

// CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
// uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;

CAN_TxHeaderTypeDef txHeader =
{
    .StdId = 0x00,                  // 标准 can id (11bit 0~0x7FF)
    .ExtId = 0x0000,                // 扩展 can id (29bit 0~0x1FFFFFFF)
    .IDE = CAN_ID_STD,              // 标准帧CAN_ID_STD/扩展帧CAN_ID_EXT
    .RTR = CAN_RTR_DATA,            // 数据帧CAN_RTR_DATA/远程帧CAN_RTR_REMOTE
    .DLC = 8,                       // 数据长度[0,8]
    .TransmitGlobalTime = DISABLE   // 不使用全局时间
};

void bsp_can_init(void)
{
    CAN_FilterTypeDef sFilterConfig;
    //filter one (stack light blink)
    sFilterConfig.FilterBank = 0;
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x0000;
    sFilterConfig.FilterIdLow = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0000;
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
    sFilterConfig.FilterActivation = ENABLE;
    sFilterConfig.SlaveStartFilterBank = 14;
    if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
    {
        /* Filter configuration Error */
        Error_Handler();
    }

    HAL_CAN_Start(&hcan); //start CAN

    HAL_CAN_ActivateNotification(&hcan,
                                 CAN_IT_TX_MAILBOX_EMPTY |
                                 CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING |
                                 /* we probably only want this */
                                 CAN_IT_RX_FIFO0_FULL | CAN_IT_RX_FIFO1_FULL |
                                 CAN_IT_RX_FIFO0_OVERRUN | CAN_IT_RX_FIFO1_OVERRUN |
                                 CAN_IT_WAKEUP | CAN_IT_SLEEP_ACK |
                                 CAN_IT_ERROR_WARNING | CAN_IT_ERROR_PASSIVE |
                                 CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE |
                                 CAN_IT_ERROR);
/* Configure Transmission process */
    // TxHeader.StdId = boardConfig.canNodeId; // 标准 can id (11bit 0~0x7FF)
    // TxHeader.ExtId = 0x0000;                // 扩展 can id (29bit 0~0x1FFFFFFF)
    // TxHeader.RTR = CAN_RTR_DATA;            // 数据帧CAN_RTR_DATA/远程帧CAN_RTR_REMOTE
    // TxHeader.IDE = CAN_ID_STD;              // 标准帧CAN_ID_STD/扩展帧CAN_ID_EXT
    // TxHeader.DLC = 8;                       // 数据长度[0,8]
    // TxHeader.TransmitGlobalTime = DISABLE;  // 不使用全局时间
}


void CAN_Send_Data(uint8_t id, uint8_t cmd, const uint8_t* data)
{
    txHeader.StdId = (id&0x0F << 7) | (cmd & 0x7F); // 4Bits ID & 7Bits Msg
    if (HAL_CAN_AddTxMessage(&hcan, &txHeader, (uint8_t*)data, &TxMailbox) != HAL_OK)
    {
        Error_Handler();
    }
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* CanHandle)
{
    /* Get RX message */
    if (HAL_CAN_GetRxMessage(CanHandle, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
    {
        /* Reception Error */
        Error_Handler();
    }

    uint8_t id = (RxHeader.StdId >> 7); // 4Bits ID & 7Bits Msg
    uint8_t cmd = RxHeader.StdId & 0x7F; // 4Bits ID & 7Bits Msg
    OnCanCmd(id, cmd, RxData, RxHeader.DLC);
}
